-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix URLSession crashing on HTTP/0.9 simple-responses #1097
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix URLSession crashing on HTTP/0.9 simple-responses #1097
Conversation
@swift-ci please test |
@@ -41,6 +41,10 @@ class TestURLSession : XCTestCase { | |||
("test_customProtocolResponseWithDelegate", test_customProtocolResponseWithDelegate), | |||
("test_httpRedirection", test_httpRedirection), | |||
("test_httpRedirectionTimeout", test_httpRedirectionTimeout), | |||
("test_illegalHTTPServerResponses", test_illegalHTTPServerResponses), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're keeping the order of the tests the same as in the test list, this line should be moved to the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @alblue , addressed
@swift-ci please test |
1 similar comment
@swift-ci please test |
This is interesting. The change and the tests look good to me. Does Foundation on Darwin also gracefully handle such responses? |
@pushkarnk two intentions in this pull request
I haven't tried how regular Foundation behaves, but it certainly won't just crash ;). Do we want to match regular Foundation exactly or what is the intention here? With my patch we handle these not so common server responses just the way CURL handles them which is what we seem to do usually in Swift Foundation's URLSession. |
@pushkarnk @parkera @phausler My suggestion would be to get this patch in as soon as possible to be sure it'll land in Swift 4 as it's just terrible if the program crashes if the server misbehaves. Worst is that if you connect to HTTP2-only servers you might hit that behaviour (as a HTTP2 only response looks like a HTTP/0.9 simple-response to CURL versions without HTTP2 support). After we addressed the crasher issues we should talk about what we want to achieve here and how we want to handle all the special cases. See here for the list of odd server behaviours I could quickly come up with. We should then go through that list one by one and decide what the appropriate behaviour should be. But IMHO more importantly we should get something in to fix the crashes. We can then always decide later that we want to throw away HTTP/0.9 simple responses even though CURL handles them. |
Specifically, if the server is using HTTP/1.1 but the header is malformed (as you've demonstrated in the tests) does Darwin also return an HTTPURLResponse with httpVersion set to 0.9? |
Yes, we'd ideally want to. Unless we are sure that the Darwin Foundation isn't doing the right thing |
guard ts.isHeaderComplete else { fatalError("Received body data, but the header is not complete, yet.") } | ||
guard case .transferInProgress(var ts) = internalState else { fatalError("Received body data, but no transfer in progress.") } | ||
if !ts.isHeaderComplete { | ||
ts.response = HTTPURLResponse(url: ts.url, statusCode: 200, httpVersion: "0.9", headerFields: [:]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this valid in the three different scenarios that you have pointed out?
- When the server sends a HTTP/0.9 response aka "only the body"
- When the server is running HTTP/1.1 but sends a malformed response
- When the server running HTTP/2 sends a response to client running HTTP/1.1
... I'm specifically concerned about thehttpVersion: "0.9"
In short, I seem to have only two questions:
Having said that, I agree that we need to fix these crashes first. |
@pushkarnk so in Darwin Foundation, it's really a
so it does indeed treat it as HTTP/0.9 too but the string seems to be |
also add tests for misbehaving HTTP servers.
@pushkarnk also the |
@swift-ci please test |
1 similar comment
@swift-ci please test |
@pushkarnk tests seemed to have passed. Any further comments/questions? @phausler happy with this? |
The change looks sensible to me |
also add tests for misbehaving HTTP servers.
also add tests for misbehaving HTTP servers.
we discovered that if the server is just returning random bytes, the whole app would crash with
fatalError("Received body data, but the header is not complete, yet.")
. The reason we can get into that state is that CURL support HTTP/0.9 simple-responses which are just the body bytes...The issue is also discussed on CURL's github.
To make sure we don't regress and to document the current behaviour, I also wrote tests for a few other cases when the HTTP server is misbehaving or behaving oddly.